/*************************************************
* Title：TinyToolKit
* Author：Opportunity 
* Describe：工具类入口，维护所有工具管理类
* CreateTime：2020-07-09 16:04:38
* Version：1.0
* Modify Recorder：
 * 2020-07-09 16:04:38
 * 将管理类的编辑器扩展迁移到独立窗口中
 * 将ScriptableObject作为配置表，用于存储程序运行数据
*************************************************/

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace TinyToolKit
{
    public class TinyTool : TMonoSingleton<TinyTool>
    {
        //采用双向链表，方便频繁的插入操作
        private LinkedList<ManagerBase> _managers = new LinkedList<ManagerBase>();

        private TinyToolSettingAsset _tinyToolSetting;

        public TinyToolSettingAsset TinyToolSetting
        {
            get
            {
                if(_tinyToolSetting == null) 
                    Init();
                return _tinyToolSetting;
            }
        }

        #region Mono Func

        private void Awake()
        {
            if(_tinyToolSetting == null)
                Init();
        }

        private void OnEnable()
        {
            SceneManager.sceneLoaded += OnSceneLoaded;
        }

        private void OnDisable()
        {
            SceneManager.sceneLoaded -= OnSceneLoaded;
        }

        //在场景切换的时候，销毁场景中多余的TinyTool
        private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
        {
            TinyTool[] mainManagers = FindObjectsOfType<TinyTool>();

            if (instance != null && mainManagers.Length > 1)
            {
                for (int i = 0; i < mainManagers.Length; i++)
                {
                    if (mainManagers[i] != instance)
                        Destroy(mainManagers[i].gameObject);
                }

                TLogTool.Error("TinyTool实例在场景中数量为:{0}，返回第一个实例,销毁其他多余实例", mainManagers.Length);
            }

            foreach (var manager in _managers)
            {
                manager.OnSceneLoaded(scene, mode);
            }
        }

        public void Update()
        {
            foreach (var manager in _managers)
            {
                manager.UpdateManager();
            }
        }

        protected override void OnDestroy()
        {
            base.OnDestroy();

            foreach (var manager in _managers)
            {
                manager.Shutdown();
            }

            _managers.Clear();
        }

        #endregion

        #region Internal Func

        private void Init()
        {
            _tinyToolSetting = Resources.Load<TinyToolSettingAsset>("TinyToolSetting");
            if (_tinyToolSetting != null && _tinyToolSetting.persist)
                DontDestroyOnLoad(this);
        }

        #endregion

        #region Public Func

        /// <summary>
        /// 获取工具管理类，如果不存在则创建
        /// </summary>
        /// <returns>返回需要的管理类</returns>
        /// <typeparam name="T">指定管理类的类型</typeparam>
        public T GetManager<T>() where T : class
        {
            Type managerType = typeof(T);

            return GetManager(managerType) as T;
        }

        /// <summary>
        /// 获取工具管理类，如果不存在则创建   
        /// </summary>
        /// <returns>返回需要的管理类</returns>
        /// <param name="managerType">指定管理类的类型</param>
        private ManagerBase GetManager(Type managerType)
        {
            foreach (var manager in _managers)
            {
                if (manager.GetType() == managerType)
                {
                    return manager;
                }
            }

            return CreateManager(managerType);
        }

        public bool HasManager<T>() where T : class
        {
            return HasManager(typeof(T));
        }

        public bool HasManager(Type managerType)
        {
            foreach (var manager in _managers)
            {
                if (manager.GetType() == managerType)
                {
                    return true;
                }
            }

            return false;
        }

        //创建工具管理类,并完成管理类的初始化
        private ManagerBase CreateManager(Type managerType)
        {
            ManagerBase managerBase = Activator.CreateInstance(managerType) as ManagerBase;

            if (managerBase == null)
            {
                TLogTool.Error(managerType.FullName + "管理类创建失败");
                return null;
            }

            //根据优先级决定管理类在列表中的前后顺序
            LinkedListNode<ManagerBase> current = _managers.First;
            while (current != null)
            {
                if (managerBase.Priority > current.Value.Priority) break;
                current = current.Next;
            }

            if (current != null)
                _managers.AddBefore(current, managerBase);
            else
                _managers.AddLast(managerBase);

            //初始化
            managerBase.Init();
            return managerBase;
        }

        #endregion
    }
}